Ilg'or UI boshqaruvi, modal oynalar, maslahatlar va CSS z-index cheklovlarini yengib o'tish orqali haqiqiy global auditoriya uchun Reactning `createPortal` imkoniyatlarini oching.
UI Qatlamlarini Mukammal O'zlashtirish: Reactning `createPortal` Funksiyasini Chuqur O'rganish
Zamonaviy veb-dasturlashda uzluksiz va intuitiv foydalanuvchi interfeyslarini yaratish juda muhimdir. Ko'pincha, bu o'zining ota-ona komponentining DOM ierarxiyasidan tashqariga chiqishi kerak bo'lgan elementlarni ko'rsatishni o'z ichiga oladi. Modal dialoglar, bildirishnoma bannerlari, maslahatlar yoki hatto murakkab kontekst menyularini o'ylab ko'ring. Ushbu UI elementlari to'g'ri render qilinishini ta'minlash uchun tez-tez maxsus ishlov berishni talab qiladi, ular CSS z-index stacking kontekstlarining aralashuvisiz boshqa tarkib ustida joylashadi.
React o'zining uzluksiz rivojlanishida aynan shu muammo uchun kuchli yechimni taqdim etadi: createPortal funksiyasi. react-dom orqali mavjud bo'lgan ushbu xususiyat, bola komponentlarni oddiy React komponent ierarxiyasidan tashqarida mavjud bo'lgan DOM tuguniga render qilish imkonini beradi. Ushbu blog posti createPortalni tushunish va undan samarali foydalanish uchun keng qamrovli qo'llanma bo'lib xizmat qiladi, uning asosiy tushunchalari, amaliy qo'llanilishi va global dasturchilar auditoriyasi uchun eng yaxshi amaliyotlarini o'rganadi.
createPortal nima va undan nima uchun foydalanish kerak?
Asosan, React.createPortal(child, container) bu React komponentini (child) React daraxtidagi ota-ona komponentdan farqli bo'lgan boshqa DOM tuguniga (container) render qiladigan funksiyadir.
Keling, parametrlarni tahlil qilamiz:
child: Bu siz render qilmoqchi bo'lgan React elementi, satr yoki fragment. Bu siz odatda komponentningrendermetodidan qaytaradigan narsadir.container: Bu sizning hujjatingizda mavjud bo'lgan DOM elementi. Buchildqo'shiladigan nishondir.
Muammo: DOM Ierarxiyasi va CSS Stacking Kontekstlari
Keng tarqalgan stsenariyni ko'rib chiqaylik: modal dialog. Modallar odatda sahifadagi boshqa barcha kontentning ustida ko'rsatilishi mo'ljallangan. Agar siz modal komponentni to'g'ridan-to'g'ri cheklovchi overflow: hidden uslubi yoki ma'lum bir z-index qiymatiga ega bo'lgan boshqa komponent ichida render qilsangiz, modal kesilishi yoki noto'g'ri qatlamlanishi mumkin. Bu DOMning ierarxik tabiati va CSSning z-index stacking kontekst qoidalari bilan bog'liq.
Elementdagi z-index qiymati faqat uning bir xil stacking kontekstidagi qardosh elementlarga nisbatan qatlamlash tartibiga ta'sir qiladi. Agar ajdod element yangi stacking kontekstini o'rnatsa (masalan, static dan boshqa position va z-index ga ega bo'lish orqali), o'sha ajdod ichida render qilingan bolalar o'sha kontekst bilan cheklanadi. Bu sizning mo'ljallangan qatlamingiz boshqa elementlar ostida ko'milgan holda qoladigan umidsiz tartib muammolariga olib kelishi mumkin.
Yechim: Yordamga keladigan `createPortal`
createPortal komponentning React daraxtidagi o'rni va uning DOM daraxtidagi o'rni o'rtasidagi vizual aloqani uzish orqali bu muammoni oqilona hal qiladi. Siz komponentni portal ichida render qilishingiz mumkin va u to'g'ridan-to'g'ri bodyning qardoshi yoki bolasi bo'lgan DOM tuguniga qo'shiladi, bu esa muammoli ajdod stacking kontekstlarini samarali ravishda chetlab o'tadi.
Portal o'z bolasini boshqa DOM tuguniga render qilsa ham, u hali ham React daraxtingizdagi oddiy React komponenti kabi harakat qiladi. Bu shuni anglatadiki, hodisalarning tarqalishi kutilganidek ishlaydi: agar portal tomonidan render qilingan komponentga hodisa ishlovchisi biriktirilgan bo'lsa, hodisa faqat DOM ierarxiyasi bo'ylab emas, balki React komponent ierarxiyasi bo'ylab ham yuqoriga ko'tariladi.
createPortal uchun asosiy foydalanish holatlari
createPortalning ko'p qirraliligi uni turli UI naqshlari uchun ajralmas vositaga aylantiradi:
1. Modal Oynalar va Dialoglar
Bu, ehtimol, eng keng tarqalgan va jozibali foydalanish holatidir. Modallar foydalanuvchining ish jarayonini to'xtatish va e'tiborni talab qilish uchun mo'ljallangan. Ularni to'g'ridan-to'g'ri komponent ichida render qilish stacking kontekst muammolariga olib kelishi mumkin.
Misol stsenariysi: Foydalanuvchilar buyurtmani tasdiqlashi kerak bo'lgan elektron tijorat ilovasini tasavvur qiling. Tasdiqlash modali sahifadagi hamma narsaning ustida paydo bo'lishi kerak.
Amalga oshirish g'oyasi:
- Sizning
public/index.htmlfaylingizda maxsus DOM elementini yarating (yoki dinamik ravishda yarating). Keng tarqalgan amaliyot<div id="modal-root"></div>ga ega bo'lishdir, u ko'pincha<body>tegi oxirida joylashtiriladi. - React ilovangizda ushbu DOM tuguniga havola oling.
- Modal komponentingiz ishga tushirilganda, modal tarkibini
modal-rootDOM tuguniga render qilish uchunReactDOM.createPortaldan foydalaning.
Kod parchasi (Konseptual):
// App.js
import React from 'react';
import Modal from './Modal';
function App() {
const [isModalOpen, setIsModalOpen] = React.useState(false);
return (
Welcome to Our Global Store!
{isModalOpen && (
setIsModalOpen(false)}>
Confirm Your Purchase
Are you sure you want to proceed?
)}
);
}
export default App;
// Modal.js
import React from 'react';
import ReactDOM from 'react-dom';
const modalRoot = document.getElementById('modal-root');
function Modal({ children, onClose }) {
// Create a DOM element for the modal content to live in
const element = document.createElement('div');
React.useEffect(() => {
// Append the element to the modal root when the component mounts
modalRoot.appendChild(element);
// Clean up by removing the element when the component unmounts
return () => {
modalRoot.removeChild(element);
};
}, [element]);
return ReactDOM.createPortal(
{children}
,
element // Render into the element we created
);
}
export default Modal;
Ushbu yondashuv modalning modal-rootning to'g'ridan-to'g'ri bolasi bo'lishini ta'minlaydi, bu odatda bodyga qo'shiladi va shu bilan har qanday oraliq stacking kontekstlarini chetlab o'tadi.
2. Maslahatlar (Tooltips) va Qalqib chiquvchi oynalar (Popovers)
Maslahatlar va qalqib chiquvchi oynalar - bu foydalanuvchi boshqa element bilan o'zaro aloqada bo'lganda (masalan, tugmachani bosganda yoki belgi ustiga sichqonchani olib borganda) paydo bo'ladigan kichik UI elementlari. Ular, ayniqsa, ishga tushiruvchi element murakkab tartibda chuqur joylashgan bo'lsa, boshqa tarkib ustida paydo bo'lishi kerak.
Misol stsenariysi: Xalqaro hamkorlik platformasida foydalanuvchi jamoa a'zosining aloqa ma'lumotlari va mavjudlik holatini ko'rish uchun uning avatari ustiga sichqonchani olib boradi. Maslahat avatarning ota-ona konteynerining uslubidan qat'i nazar ko'rinishi kerak.
Amalga oshirish g'oyasi: Modallarga o'xshab, maslahatlarni render qilish uchun portal yaratishingiz mumkin. Keng tarqalgan naqsh - bu maslahatni umumiy portal ildiziga yoki hatto maxsus portal konteyneringiz bo'lmasa, to'g'ridan-to'g'ri bodyga biriktirishdir.
Kod parchasi (Konseptual):
// Tooltip.js
import React from 'react';
import ReactDOM from 'react-dom';
function Tooltip({ children, targetElement }) {
if (!targetElement) return null;
// Render the tooltip content directly into the body
return ReactDOM.createPortal(
{children}
,
document.body
);
}
// Parent Component that triggers the tooltip
function InfoButton({ info }) {
const [targetRef, setTargetRef] = React.useState(null);
const [showTooltip, setShowTooltip] = React.useState(false);
return (
setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
style={{ position: 'relative', display: 'inline-block' }}
>
? {/* Information icon */}
{showTooltip && {info} }
);
}
3. Ochiladigan menyular va Tanlash qutilari
Maxsus ochiladigan menyular va tanlash qutilari ham portallardan foyda ko'rishi mumkin. Ochiladigan menyu ochilganda, u ko'pincha o'zining ota-ona konteynerining chegaralaridan tashqariga chiqishi kerak bo'ladi, ayniqsa, agar o'sha konteynerda overflow: hidden kabi xususiyatlar bo'lsa.
Misol stsenariysi: Ko'p millatli kompaniyaning ichki boshqaruv panelida uzun ro'yxatdan loyihani tanlash uchun maxsus tanlash ochiladigan menyusi mavjud. Ochiladigan ro'yxat u joylashgan boshqaruv paneli vidjetining kengligi yoki balandligi bilan cheklanmasligi kerak.
Amalga oshirish g'oyasi: Ochiladigan menyu parametrlarini bodyga yoki maxsus portal ildiziga biriktirilgan portalga render qiling.
4. Bildirishnoma Tizimlari
Global bildirishnoma tizimlari (toast xabarlari, ogohlantirishlar) createPortal uchun yana bir ajoyib nomzoddir. Ushbu xabarlar odatda joriy aylantirish pozitsiyasi yoki ota-ona komponentining tartibidan qat'i nazar, ko'rish oynasining yuqori yoki pastki qismida qat'iy pozitsiyada paydo bo'ladi.
Misol stsenariysi: Sayohat bron qilish sayti muvaffaqiyatli bronlar uchun tasdiqlash xabarlarini yoki muvaffaqiyatsiz to'lovlar uchun xato xabarlarini ko'rsatadi. Ushbu bildirishnomalar foydalanuvchi ekranida doimiy ravishda paydo bo'lishi kerak.
Amalga oshirish g'oyasi: Maxsus bildirishnoma konteyneri (masalan, <div id="notifications-root"></div>) createPortal bilan ishlatilishi mumkin.
Reactda `createPortal` qanday amalga oshiriladi
createPortalni amalga oshirish bir necha asosiy qadamlarni o'z ichiga oladi:
1-qadam: Nishon DOM tugunini aniqlash yoki yaratish
Sizga portal tarkibingiz uchun konteyner sifatida xizmat qilish uchun standart React ildizidan tashqarida DOM elementi kerak. Eng keng tarqalgan amaliyot bu elementni asosiy HTML faylingizda (masalan, public/index.html) aniqlashdir.
<!-- public/index.html -->
<body>
<noscript>You need JavaScript enabled to run this app.</noscript>
<div id="root"></div>
<div id="modal-root"></div> <!-- Modallar uchun -->
<div id="tooltip-root"></div> <!-- Ixtiyoriy ravishda maslahatlar uchun -->
</body>
Shu bilan bir qatorda, yuqoridagi Modal misolida ko'rsatilganidek, JavaScript yordamida ilovangizning hayot tsikli ichida dinamik ravishda DOM elementini yaratishingiz va keyin uni DOMga qo'shishingiz mumkin. Biroq, doimiy portal ildizlari uchun HTMLda oldindan aniqlash odatda tozaroq bo'ladi.
2-qadam: Nishon DOM tuguniga havola olish
React komponentingizda siz ushbu DOM tuguniga kirishingiz kerak bo'ladi. Buni document.getElementById() yoki document.querySelector() yordamida qilishingiz mumkin.
// Komponentingiz yoki yordamchi faylingizning biror joyida
const modalRootElement = document.getElementById('modal-root');
const tooltipRootElement = document.getElementById('tooltip-root');
// Ulardan foydalanishga harakat qilishdan oldin ushbu elementlarning mavjudligiga ishonch hosil qilish juda muhim.
// Ular topilmagan holatlar uchun tekshiruvlar qo'shishingiz yoki ularni hal qilishingiz mumkin.
3-qadam: `ReactDOM.createPortal`dan foydalanish
ReactDOMni import qiling va createPortal funksiyasidan foydalaning, komponentingizning JSXini birinchi argument sifatida va nishon DOM tugunini ikkinchi argument sifatida o'tkazing.
Misol: Portalda oddiy xabar render qilish
// MessagePortal.js
import React from 'react';
import ReactDOM from 'react-dom';
function MessagePortal({ message }) {
const portalContainer = document.getElementById('modal-root'); // Bu misol uchun modal-root ishlatayotganingizni taxmin qilamiz
if (!portalContainer) {
console.error('Portal container "modal-root" not found!');
return null;
}
return ReactDOM.createPortal(
<div style={{ position: 'fixed', bottom: '20px', left: '50%', transform: 'translateX(-50%)', backgroundColor: 'rgba(0,0,0,0.7)', color: 'white', padding: '10px', borderRadius: '5px' }}>
{message}
</div>,
portalContainer
);
}
export default MessagePortal;
// Boshqa komponentda...
function Dashboard() {
return (
<div>
<h1>Dashboard Overview</h1>
<MessagePortal message="Data successfully synced!" />
</div>
);
}
Portallar bilan holat va hodisalarni boshqarish
createPortalning eng muhim afzalliklaridan biri shundaki, u Reactning hodisalarni qayta ishlash tizimini buzmaydi. Portal ichida render qilingan elementlardan kelib chiqadigan hodisalar faqat DOM daraxti bo'ylab emas, balki React komponent daraxti bo'ylab yuqoriga ko'tariladi.
Misol stsenariysi: Modal dialog shaklni o'z ichiga olishi mumkin. Foydalanuvchi modal ichidagi tugmani bosganda, bosish hodisasi modalning ko'rinishini boshqaradigan ota-ona komponentdagi hodisa tinglovchisi tomonidan qayta ishlanishi kerak, modalning o'zining DOM ierarxiyasi ichida qolib ketmasligi kerak.
Tasviriy misol:
// ModalWithEventHandling.js
import React from 'react';
import ReactDOM from 'react-dom';
const modalRoot = document.getElementById('modal-root');
function ModalWithEventHandling({ children, onClose }) {
const modalContentRef = React.useRef(null);
// Using useEffect to create and clean up the DOM element
const [wrapperElement] = React.useState(() => document.createElement('div'));
React.useEffect(() => {
modalRoot.appendChild(wrapperElement);
return () => {
modalRoot.removeChild(wrapperElement);
};
}, [wrapperElement]);
// Handle clicks outside the modal content to close it
const handleOutsideClick = (event) => {
if (modalContentRef.current && !modalContentRef.current.contains(event.target)) {
onClose();
}
};
return ReactDOM.createPortal(
{children}
,
wrapperElement
);
}
// App.js (using the modal)
function App() {
const [showModal, setShowModal] = React.useState(false);
return (
App Content
{showModal && (
setShowModal(false)}>
Important Information
This is content inside the modal.
)}
);
}
Ushbu misolda, Close Modal tugmachasini bosish ota-ona App komponentidan o'tkazilgan onClose propini to'g'ri chaqiradi. Xuddi shunday, agar sizda modal-backdropdagi bosishlar uchun hodisa tinglovchisi bo'lsa, u handleOutsideClick funksiyasini to'g'ri ishga tushiradi, garchi modal alohida DOM quyi daraxtiga render qilingan bo'lsa ham.
Ilg'or naqshlar va mulohazalar
Dinamik Portallar
Siz ilovangizning ehtiyojlariga qarab portal konteynerlarini dinamik ravishda yaratishingiz va olib tashlashingiz mumkin, ammo doimiy, oldindan belgilangan portal ildizlarini saqlash ko'pincha osonroqdir.
Portallar va Server Tomonidan Renderlash (SSR)
Server tomonida renderlash (SSR) bilan ishlaganda, portallarning dastlabki HTML bilan qanday o'zaro ta'sir qilishiga e'tibor berishingiz kerak. Portallar serverda mavjud bo'lmasligi mumkin bo'lgan DOM tugunlariga render qilinganligi sababli, siz ko'pincha portal tarkibini shartli ravishda render qilishingiz yoki nishon DOM tugunlarining SSR chiqishida mavjudligini ta'minlashingiz kerak bo'ladi.
Keng tarqalgan naqsh - bu useIsomorphicLayoutEffect (yoki mijozda useLayoutEffectni ustuvor qiladigan va serverda useEffectga qaytadigan maxsus hook) kabi hookdan foydalanishdir, bu DOM manipulyatsiyasi faqat mijozda sodir bo'lishini ta'minlaydi.
// usePortal.js (a common utility hook pattern)
import React, { useRef, useEffect } from 'react';
function usePortal(id) {
const modalRootRef = useRef(null);
useEffect(() => {
let currentModalRoot = document.getElementById(id);
if (!currentModalRoot) {
currentModalRoot = document.createElement('div');
currentModalRoot.setAttribute('id', id);
document.body.appendChild(currentModalRoot);
}
modalRootRef.current = currentModalRoot;
// Cleanup function to remove the created element if it was created by this hook
return () => {
// Be cautious with cleanup; only remove if it was actually created here
// A more robust approach might involve tracking element creation.
};
}, [id]);
return modalRootRef.current;
}
export default usePortal;
// Modal.js (using the hook)
import React from 'react';
import ReactDOM from 'react-dom';
import usePortal from './usePortal';
function Modal({ children, onClose }) {
const portalTarget = usePortal('modal-root'); // Use our hook
if (!portalTarget) return null;
return ReactDOM.createPortal(
e.stopPropagation()}> {/* Prevent closing by clicking inside */}
{children}
,
portalTarget
);
}
SSR uchun siz odatda modal-root divining serverda render qilingan HTMLda mavjudligini ta'minlashingiz kerak bo'ladi. Keyin mijozdagi React ilovasi unga birikadi.
Portallarni uslublash
Portal ichidagi elementlarni uslublash ehtiyotkorlik bilan ko'rib chiqishni talab qiladi. Ular ko'pincha to'g'ridan-to'g'ri ota-onaning uslublash kontekstidan tashqarida bo'lganligi sababli, portal tarkibining ko'rinishini samarali boshqarish uchun global uslublarni qo'llashingiz yoki CSS modullari/styled-komponentlardan foydalanishingiz mumkin.
Modallar kabi qatlamlar uchun sizga ko'pincha quyidagi uslublar kerak bo'ladi:
- Elementni ko'rish oynasiga mahkamlash (
position: fixed). - Butun ko'rish oynasini qamrab olish (
top: 0; left: 0; width: 100%; height: 100%;). - Uning hamma narsadan yuqorida paydo bo'lishini ta'minlash uchun yuqori
z-indexqiymatidan foydalanish. - Orqa fon uchun yarim shaffof fonni kiritish.
Foydalanish imkoniyati (Accessibility)
Modallar yoki boshqa qatlamlarni amalga oshirishda foydalanish imkoniyati juda muhimdir. Fokusni to'g'ri boshqarishingizga ishonch hosil qiling:
- Modal ochilganda, fokusni modal ichida ushlab qoling. Foydalanuvchilar undan tashqariga tab tugmasi bilan o'ta olmasliklari kerak.
- Modal yopilganda, fokusni uni ishga tushirgan elementga qaytaring.
- Yordamchi texnologiyalarga modalning tabiati haqida ma'lumot berish uchun ARIA atributlaridan (masalan,
role="dialog",aria-modal="true",aria-labelledby,aria-describedby) foydalaning.
Reach UI yoki Material-UI kabi kutubxonalar ko'pincha siz uchun ushbu muammolarni hal qiladigan, foydalanish imkoniyati mavjud bo'lgan modal komponentlarini taqdim etadi.
Potensial xatolar va ulardan qanday qochish kerak
Nishon DOM tugunini unutish
Eng keng tarqalgan xato - bu HTMLda nishon DOM tugunini yaratishni unutish yoki JavaScriptda unga to'g'ri havola qilmaslik. Har doim portal konteyneringiz mavjudligiga ishonch hosil qiling, undan keyin unga render qilishga harakat qiling.
Hodisalarning ko'tarilishi (Event Bubbling) va DOMning ko'tarilishi (DOM Bubbling)
React hodisalari portallar orqali to'g'ri ko'tarilsa-da, mahalliy DOM hodisalari bunday qilmaydi. Agar siz portal ichidagi elementlarga to'g'ridan-to'g'ri mahalliy DOM hodisa tinglovchilarini biriktirayotgan bo'lsangiz, ular faqat DOM daraxti bo'ylab yuqoriga ko'tariladi, React komponent daraxti bo'ylab emas. Iloji boricha Reactning sintetik hodisalar tizimiga rioya qiling.
Bir-biriga yopishib qolgan portallar
Agar sizda bir nechta turdagi qatlamlar (modallar, maslahatlar, bildirishnomalar) bo'lsa, ularning barchasi bodyga yoki umumiy ildizga render qilinsa, ularning qatlamlash tartibini boshqarish murakkablashishi mumkin. Muayyan z-index qiymatlarini belgilash yoki portalni boshqarish tizimidan foydalanish yordam berishi mumkin.
Ishlash samaradorligi bo'yicha mulohazalar
createPortal o'zi samarali bo'lsa-da, portallar ichida murakkab komponentlarni render qilish hali ham ishlash samaradorligiga ta'sir qilishi mumkin. Portal tarkibingiz optimallashtirilganligiga va keraksiz qayta renderlardan qochishga ishonch hosil qiling.
`createPortal`ga muqobillar
createPortal bu stsenariylarni hal qilishning idiomatik React usuli bo'lsa-da, siz duch kelishingiz yoki ko'rib chiqishingiz mumkin bo'lgan boshqa yondashuvlarni qayd etishga arziydi:
- To'g'ridan-to'g'ri DOM manipulyatsiyasi: Siz
document.createElementvaappendChildyordamida DOM elementlarini qo'lda yaratishingiz va qo'shishingiz mumkin, ammo bu Reactning deklarativ renderlash va holatni boshqarish tizimini chetlab o'tadi, bu esa uni kamroq saqlanuvchan qiladi. - Yuqori darajali komponentlar (HOCs) yoki Render Proplar: Ushbu naqshlar portal renderlash mantig'ini abstraktlashtirishi mumkin, ammo
createPortalo'zi asosiy mexanizmdir. - Komponent kutubxonalari: Ko'pgina UI komponent kutubxonalari (masalan, Material-UI, Ant Design, Chakra UI)
createPortaldan foydalanishni abstraktlashtiradigan oldindan qurilgan modal, maslahat va ochiladigan menyu komponentlarini taqdim etadi, bu esa dasturchilar uchun qulayroq tajriba beradi. Biroq, ushbu komponentlarni sozlash yoki o'zingiznikini yaratish uchuncreatePortalni tushunish juda muhimdir.
Xulosa
React.createPortal Reactda murakkab foydalanuvchi interfeyslarini yaratish uchun kuchli va muhim xususiyatdir. Komponentlarni o'zlarining React daraxt ierarxiyasidan tashqaridagi DOM tugunlariga render qilish imkonini berish orqali u CSS z-index, stacking kontekstlari va elementlarning toshib ketishi bilan bog'liq keng tarqalgan muammolarni samarali hal qiladi.
Foydalanuvchi tasdiqlashi uchun murakkab modal dialoglar, kontekstli ma'lumotlar uchun nozik maslahatlar yoki global ko'rinadigan bildirishnoma bannerlarini yaratayotgan bo'lsangiz ham, createPortal kerakli moslashuvchanlik va nazoratni ta'minlaydi. Turli texnik bilim va ehtiyojlarga ega bo'lgan global auditoriya uchun mos keladigan, haqiqatan ham mustahkam va foydalanuvchiga qulay ilova uchun portal DOM tugunlarini boshqarishni, hodisalarni to'g'ri qayta ishlashni va foydalanish imkoniyati va ishlash samaradorligini birinchi o'ringa qo'yishni unutmang.
createPortalni o'zlashtirish, shubhasiz, sizning React dasturlash mahoratingizni oshiradi va zamonaviy veb-ilovalarning tobora murakkablashib borayotgan landshaftida ajralib turadigan yanada silliq va professional UI yaratishga imkon beradi.